/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/

/**
 * @brief  Define command line arguments for the driver of AMCC.
 *
 * @author  WXQ#XDU
 * @date    2024.12
 */


#include <stdio.h>
#include <string.h>

#include "amcc_main.h"

#define CLOPT_INPUT     "-i"
#define CLOPT_OUTDIR    "-od"
#define CLOPT_LOGLVL    "-loglevel"
#define CLOPT_LOGTIME   "-logtime"
#define CLOPT_LOGSRC    "-logsrc"
#define CLOPT_LOGSOURCE "-logsource"
#define CLOPT_LOGRDF    "-logrdf"
#define CLOPT_PHASE     "-phase"
#define CLOPT_MAIN      "-main"
#define CLOPT_TEMPVAR   "-t"

void  print_usage (const char* argv0)
{
    SHOW_MSG("\nUsage: %s -i input-file-path  [OPTIONS]\n\n",
           path_basename( argv0 ) );

    SHOW_MSG("All optional arguments in OPTIONS are listed below:\n"
           CLOPT_OUTDIR
                " <dir>   Set the directory to store output files.\n"
                "            Default is [%s/].\n"
           CLOPT_LOGLVL
                " <name>   Set the log level, default is INFO.\n"
                "           The name is one of TRACE, DEBUG, INFO, WARN, ERROR.\n"
           CLOPT_LOGTIME
                "   Show time stamp in log file.\n"
           CLOPT_LOGSRC
                "    Show AMCC source file name in log file.\n"
           CLOPT_LOGRDF
                "    Show call-stack of Recursive-Descent-Functions in log file.\n"
                "           This function is only work at loglevel is DEBUG or TRACE.\n"
           CLOPT_PHASE
                "     The phases (1,2,etc) to be executed.\n"
                "\n"
           , amcc_get_outputDir()
    );

}



int parse_command_line (t_workdata_ptr pWorkdata,
                        int argc, char *argv[] )
{
    if (argc < 3)   return -1;

    bool isInput = false;
    int k;
    char * arg;
    for ( k = 1, arg = argv[k]; k < argc; arg = argv[++k] ) {
        if ( 0 == strcmp( CLOPT_INPUT, arg ) ) {
            if ( NULL == argv[ ++k ] ) {
                SHOW_MSG("*** Missing input-file-path for argument \"" CLOPT_INPUT  "\".\n");
                return 1;
            }
            isInput = true;
            amcc_set_inputFilePath(argv[k]);
            continue;
        }
        else if ( 0 == strcmp( CLOPT_OUTDIR, arg ) ) {
            if ( NULL == argv[ ++k ] ) {
                SHOW_MSG("*** Missing output-dir for argument \"" CLOPT_OUTDIR  "\".\n");
                return 1;
            }
            amcc_set_outputDir(argv[k]);
            continue;
        }
        else if ( 0 == strcmp( CLOPT_LOGLVL, arg ) ) {
            char * lvlName = argv[ ++k ];
            EnumLogLevel  enumLevel = (EnumLogLevel) amcc_get_logLevel();
            if ( NULL == lvlName ) {
                SHOW_MSG("*** Missing log-level-name for argument \"" CLOPT_LOGLVL  "\".\n");
                return 1;
            }
            else if ( 0 == cstring_cmp_icase("TRACE", lvlName) )
                enumLevel = LOG_TRACE;
            else if ( 0 == cstring_cmp_icase("DEBUG", lvlName) )
                enumLevel = LOG_DEBUG;
            else if ( 0 == cstring_cmp_icase("INFO", lvlName) )
                enumLevel = LOG_INFO;
            else if ( 0 == cstring_cmp_icase("WARN", lvlName) )
                enumLevel = LOG_WARN;
            else if ( 0 == cstring_cmp_icase("ERROR", lvlName) )
                enumLevel = LOG_ERROR;
            else {
                SHOW_MSG("*** Unknown log-level-name \"%s\"\n", lvlName);
                return 1;
            }

            amcc_set_logLevel(enumLevel);
            continue;
        }
        else if ( 0 == strcmp( CLOPT_LOGTIME, arg ) ) {
            amcc_set_logTime(true);
            continue;
        }
        else if (  0 == strcmp( CLOPT_LOGSRC, arg )
                   || 0 == strcmp( CLOPT_LOGSOURCE, arg ) )
        {
            amcc_set_logSource(true);
            continue;
        }
        else if ( 0 == strcmp( CLOPT_LOGRDF, arg ) ) {
            amcc_set_logParserStack(true);
            continue;
        }
        else if ( 0 == strcmp( CLOPT_PHASE, arg ) ) {
            if ( NULL == argv[ ++k ] ) {
                SHOW_MSG("*** Missing phase number for argument \"" CLOPT_PHASE  "\".\n");
                return 1;
            } else {
                long longValue = strtol(argv[k], NULL, 10);
                if( longValue <= 0) {
                    SHOW_MSG("*** Bad phase number %s, expects 1, 2, etc.\n", argv[k]);
                    return 1;
                }
                pWorkdata->targetPhase = longValue;
            }
            continue;
        }
        else if ( 0 == strcmp( CLOPT_MAIN, arg ) ) {
            amcc_set_shouldExistMain(true);
            continue;
        }
        else if ( 0 == strcmp( CLOPT_TEMPVAR, arg ) ) {
            if ( NULL == argv[ ++k ] ) {
                SHOW_MSG("*** Missing the temporary variable prefix"
                         " for argument \"" CLOPT_TEMPVAR  "\".\n");
                return 1;
            } else {
                amcc_set_tempvar_prefix(argv[k]);
            }
            continue;
        }

        SHOW_MSG("*** Unknown option \"%s\".\a\n", arg);
        return 1;
    }

    if( !isInput ) {
        SHOW_MSG("*** Missing \"-i input-file-path\" in command line.\n");
        return 2;
    }

    return 0;
}

